#include "domparser.h"
#include "defs.h"
#include "manager.h"

DomParser::DomParser(QIODevice *device, Pacient *pacient)
{
    parseSuccess = true;
    parseResult = "";
    mPacient = pacient;
    QString errorStr;
    int errorLine, errorColumn;
    QDomDocument doc;
    if(!doc.setContent(device, true, &errorStr, &errorLine, &errorColumn))
    {
        parseResult = UkrString("Помилка у вхідному файлі, рядок %1, стовпчик %2:\n%3")
                .arg(errorLine)
                .arg(errorColumn)
                .arg(errorStr);
        parseSuccess = false;
        return;
    }
    QDomElement root = doc.documentElement();
    if (root.tagName()!="pacient")
    {
        LOG("XMLParser", "Некоректний вхідний файл. Не знайдено секції <b>pacient</b>");
        parseSuccess = false;
        return;
    } else if (root.attribute("ver") != QString("%1").arg(PACIENT_VERSION))
    {
        LOG(root.attribute("ver"), "");
        parseResult = UkrString("Неправильна версія файлу (<b>%1</b>, а очікується <b>%2</b>). "
                              "Файл був створений іншою версією програми.")
                .arg(root.attribute("ver"))
                .arg(PACIENT_VERSION);
        parseSuccess = false;
        return;
    }
    QDomNode node = root.firstChild();
    while (!node.isNull())
    {
        if (node.toElement().tagName() == "fname")
        {
            mPacient->setFName( node.toElement().text() );
        }
        else if (node.toElement().tagName() == "mname")
        {
            mPacient->setMName( node.toElement().text() );
        }
        else if (node.toElement().tagName() == "lname")
        {
            mPacient->setLName( node.toElement().text() );
        }
        else if (node.toElement().tagName() == "dob")
        {
            QString tmpStrDate = node.toElement().text();
            if (!tmpStrDate.isEmpty())
            {
                QDate tmpDate(QDate::fromString(tmpStrDate, DateFormat));
                mPacient->setDob(tmpDate);
            }
        }
        else if (node.toElement().tagName() == "sex")
        {
            mPacient->setSex( node.toElement().text() );
        }
        else if (node.toElement().tagName() == "blood")
        {
            mPacient->mBlood.first = node.toElement().attribute("type").toInt();
            mPacient->mBlood.second = node.toElement().attribute("rh").toInt();
        }
        else if (node.toElement().tagName() == "lives")
        {
            mPacient->mRegion = node.toElement().attribute("region").toInt();
            mPacient->mTown = node.toElement().attribute("town");
        }
        else if (node.toElement().tagName() == "habits")
        {
            mPacient->mSmoke = node.toElement().attribute("smoke")=="1" ? true : false;
            mPacient->mAlko = node.toElement().attribute("alko")=="1" ? true : false;
            mPacient->mNarco = node.toElement().attribute("narco")=="1" ? true : false;
        }

        else if (node.toElement().tagName() == "foto")
        {
            mPacient->setFoto( node.toElement().text() );
        }
        else if (node.toElement().tagName() == "parents")
        {
            parseParents(node.toElement());
        }
        else if (node.toElement().tagName() == "operations")
        {
            parseOperations( node.toElement() );
        }
        else if (node.toElement().tagName() == "inspections")
        {
            parseInspections( node.toElement() );
        }
        else if (node.toElement().tagName() == "rentgens")
        {
            parseRentgens( node.toElement() );
        }
        else if (node.toElement().tagName() == "comment")
        {
            mPacient->setComment( node.toElement().text() );
        }
        node = node.nextSibling();
    }
}

void DomParser::parseParents(const QDomElement &element)
{
    QDomNode node = element.firstChild();
    if (node.toElement().tagName()=="father")
    {
        QString tmpStr = node.toElement().attribute("height");
        if (!tmpStr.isEmpty())
        {
            bool ok = false;
            double tmpDbl = tmpStr.toDouble(&ok);
            if (!ok) LOGGER->add("DomParser::parseParents", "Проблема з father height");
            mPacient->setHFather(tmpDbl);
        }
    }
    node = node.nextSibling();
    if (node.toElement().tagName()=="mother")
    {
        QString tmpStr = node.toElement().attribute("height");
        if (!tmpStr.isEmpty())
        {
            bool ok = false;
            double tmpDbl = node.toElement().attribute("height").toDouble(&ok);
            if (!ok) LOGGER->add("DomParser::parseParents", "Проблема з mother height");
            mPacient->setHMother(tmpDbl);
        }
    }
}

void DomParser::parseOperations(const QDomElement &element)
{ // парсинг секції операцій
    QVariantList vl;

    QDomNode node = element.firstChild();
    while(node.isElement())
    {
        if (node.toElement().tagName()=="operation")
        {
            for (int i=0; i<OperationColCount; ++i) vl.append("");

            vl[OC_Date] = node.toElement().attribute("date");
            vl[OC_Age] = node.toElement().attribute("age");
            vl[OC_Limb] = node.toElement().attribute("limb");
            vl[OC_Bone] = node.toElement().attribute("bone");
            vl[OC_Location] = node.toElement().attribute("location");
            vl[OC_Method] = node.toElement().attribute("method");
            vl[OC_Comment] = node.toElement().text();

            // додати операцію в вектор
            App->pacient()->addOperation(vl);
            // переходимо до наступної операції
            node = node.nextSibling();
        } else {
            parseResult.append("Порожня секція операцій (operations). ");
        }
    }
}

void DomParser::parseInspections(const QDomElement &element)
{ // парсинг секції обстежень
    QVariantList vl;

    QDomNode node = element.firstChild();
    while(node.hasChildNodes())
    {
        if (node.toElement().tagName()=="inspection")
        {
            for (int i=0; i<InspectionColCount; ++i) vl.append("");

            QDomNode insp = node.firstChild();
            if (insp.toElement().tagName() == "date")
            {
                QString strDate = insp.toElement().text();
                if (!strDate.isNull())
                {
                    vl[IC_Date] = strDate;
                } else { parseResult.append("Порожнє поле date в обстеженні (inspection). "); }
            }
            insp = insp.nextSibling();

            if (insp.toElement().tagName() == "age")
            {
                QString strAge = insp.toElement().text();
                vl[IC_Age] = strAge;
            }
            insp = insp.nextSibling();

            if (insp.toElement().tagName() == "limb")
            {
                QString limb = insp.toElement().text();
                vl[IC_Limb] = limb;
            }
            insp = insp.nextSibling();

            if (insp.toElement().tagName() == "stegno")
            {
                QString uStegno = insp.toElement().attribute("u");
                QString zStegno = insp.toElement().attribute("z");
                vl[IC_UStegno] = uStegno;
                vl[IC_ZStegno] = zStegno;
            }
            insp = insp.nextSibling();

            if (insp.toElement().tagName() == "vgk")
            {
                QString uVgk = insp.toElement().attribute("u");
                QString zVgk = insp.toElement().attribute("z");
                vl[IC_UVgk] = uVgk;
                vl[IC_ZVgk] = zVgk;
            }
            insp = insp.nextSibling();

            if (insp.toElement().tagName() == "mgk")
            {
                QString uMgk = insp.toElement().attribute("u");
                QString zMgk = insp.toElement().attribute("z");
                vl[IC_UMgk] = uMgk;
                vl[IC_ZMgk] = zMgk;
            }
            insp = insp.nextSibling();

            if (insp.toElement().tagName() == "stopa")
            {
                QString stopa = insp.toElement().text();
                vl[IC_Stopa] = stopa;
            }
            insp = insp.nextSibling();

            if (insp.toElement().tagName() == "promeni")
            {
                QString promeni = insp.toElement().text();
                if ( !promeni.isEmpty() )
                {
                    QStringList promeniList = promeni.split(",");
                    vl[IC_Promeni] = promeniList;
                    qDebug() << "PROMENI: " << promeniList;
                } else {
                    parseResult.append("Порожнє поле promeni в обстеженні (inspection). ");
                }
            }
            insp = insp.nextSibling();

            if (insp.toElement().tagName() == "param")
            {
                QString strHeight = insp.toElement().attribute("height");
                QString strWeight = insp.toElement().attribute("weight");
                vl[IC_Height] = strHeight;
                vl[IC_Weight] = strWeight;
            }
            insp = insp.nextSibling();
            if (insp.toElement().tagName() == "prognoz")
            {
                // TODO: check corectness
                vl[IC_Prognoz] = insp.toElement().attribute("make");
            }
            App->pacient()->addInspection(vl);

            // переходимо до наступного обстеження
            node = node.nextSibling();
        } else {
            parseResult.append("Порожня секція обстежень (inspections). ");
        }
    }
}

void DomParser::parseRentgens(const QDomElement &element)
{ // парсинг секції "рентгени"
    QDomNode node = element.firstChild();
    QVariantList vl;

    while (node.toElement().tagName()=="rentgen")
    {
        for(int i=0; i<RENT_COL_COUNT; i++)
        {
            vl.append("");
        }
        QString strName = node.toElement().attribute("name");
        QString strSrc  = node.toElement().attribute("src");
        QString strPpc  = node.toElement().attribute("ppc");
        QString strCom  = node.toElement().attribute("com");
        vl[RentName] = strName;
        vl[RentSrc] = strSrc;
        vl[RentPpc] = strPpc;
        vl[RentComment] = strCom;

        App->pacient()->addRentgen(vl);

        // переходимо до наступної фото
        node = node.nextSibling();
    }

}
